#include "MultiPredictorTFGeneralizer.h"

//individual TFGeneralizer packages
//#include "LWPRLearner.h"
#include "KDTreeLearner.h"
#include "OriginalTFGenerator.h"

MultiPredictorTFGeneralizer::MultiPredictorTFGeneralizer(MREAgent* m, int an, int od, taskspec_t& spec)
:TFGenerator(m,an,od,spec)
{

/*	//LWPR 
	LWPRLearner* ll = new LWPRLearner(m,an,od,spec); 
	predictors.push_back(ll); 
*/

	//KDTree learner
	KDTreeLearner* kdl = new KDTreeLearner(m,an,od,spec); 
	predictors.push_back(kdl); 

/*	//Original learner 
	OriginalTFGenerator* otl = new OriginalTFGenerator(m,an,od,spec); 
	predictors.push_back(otl); 
*/
}



MultiPredictorTFGeneralizer::~MultiPredictorTFGeneralizer(void)
{
	for(list<TFGenerator*>::iterator it= predictors.begin(); it != predictors.end(); it++)
		delete (*it); 
}


void MultiPredictorTFGeneralizer::learn(const Transition* t)
{
	for(list<TFGenerator*>::iterator it= predictors.begin(); it != predictors.end(); it++)
		(*it)->learn(t); 
}


Observation MultiPredictorTFGeneralizer::predict(Observation st, Action a)
{
	Observation result = new Observation_type[obs_dim]; 
	memset(result, 0, obs_dim*sizeof(double)); 
	int validResults = 0; 
	for(list<TFGenerator*>::iterator it= predictors.begin(); it != predictors.end(); it++)
	{
		Observation tmp = (*it)->predict(st,a); 
		if (tmp)
		{
			validResults++; 
			for(int i=0; i< obs_dim; i++) result[i] += tmp[i]; 

			delete[] tmp; //this was created inside the learner and we don't need it anymore
		}
	}

	//nobody returned anything good
	if(validResults==0)
	{
		delete[] result; 
		return 0; 
	}

	for(int i=0; i< obs_dim; i++) result[i] /= validResults; 

	return result; 
}

double MultiPredictorTFGeneralizer::getConfidence(Observation st, Action a)
{
	// return the max of the confidence of the individual learners
	double result = 0; 
	for(list<TFGenerator*>::iterator it= predictors.begin(); it != predictors.end(); it++)
	{
		double tmp = (*it)->getConfidence(st,a);  
		if (tmp > result)
			result = tmp; 
	}

	return result; 

}


void MultiPredictorTFGeneralizer::batchLearn(std::list<Transition>& history)
{
	for(list<TFGenerator*>::iterator it= predictors.begin(); it != predictors.end(); it++)
	{
		(*it)->batchLearn(history);   
	}
}

